package cn.sprouting.tool;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.sprouting.model.Area;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 统一社会信用代码
 *
    注：由于早期部分试点地区推行 法人和其他组织统一社会信用代码 较早，会存在部分代码不符合国家标准的情况。但它们都是合法的代码，应当另行处理。
    例如：
        福建恒跃柳工机械销售有限公司: 91350100M0001TGQXM 计算出的校验位是 1 和 M 不符
        厦门云上晴空航空科技有限公司:91350211M0000XUF46 计算出的校验位是 R 和 6 不符
        厦门黑脉网络科技有限公司91350203M0001FUE2P 计算出的校验位是 J 和 P 不符

    组成方式： 登记部门码 + 机构类别码 + 登记管理机关行政区划码 + 主体标识码（组织机构代码） + 校验码
        登记管理部门码表示登记管理部分，使用阿拉伯数字或大写英文字母表示，1代表机构编制、5代表民政、9代表工商、Y代表其他。
        机构类别码表示登记机构的类别。机构类别代码。“1”表示社会团体、“2”表示民办非企业单位、“3”表示基金会、“9”表示其他
        登记管理机关行政区划码指的是登记机构所地的行政区划代码，如350100是福建省福州市。
        主体标识码（组织机构代码）是旧的组织机构代码，按照GB 11714编码。
        最后一位是校验码，校验码计算方法参照GB/T 17710（采ISO 7064）。

 参考：
    全国企业信用公示系统 http://www.gsxt.gov.cn/
    标准：http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=24691C25985C1073D3A7C85629378AC0
    规则：https://zh.wikisource.org/wiki/GB_32100-2015_%E6%B3%95%E4%BA%BA%E5%92%8C%E5%85%B6%E4%BB%96%E7%BB%84%E7%BB%87%E7%BB%9F%E4%B8%80%E7%A4%BE%E4%BC%9A%E4%BF%A1%E7%94%A8%E4%BB%A3%E7%A0%81%E7%BC%96%E7%A0%81%E8%A7%84%E5%88%99


 * @author ：LX
 * @ Date 创建时间： 2021/10/26. 9:08
 * 地点：长沙麓谷
 * 备注说明：
 */
public class RandomUnifiedCreditCodeTool {


    /**
     * 随机生成虚假的统一信用代码
     * 注：生成的长度和规则差不多而已，可能连校验码验证都无法通过
     * @param num 生成数量
     * @param provinceCodeList 是否指定生成指定省的地区信息，注意，省市代码长度，可以为null
     * @return
     */
    public static List<String> getUnifiedCreditCode(Integer num, List<String> provinceCodeList){
        List<Area> areaList = RandomAreaTool.getArea(num, provinceCodeList, null, null);
        if (areaList == null || areaList.size() == 0){
            return null;
        }

        List<String> saveList = new ArrayList<>();
        for (Area area : areaList){
            // 共计 18位
            // 登记部门码,工商为9
            StringBuilder sb = new StringBuilder("9");
            // 机构类别码，机构类别代码。“1”表示社会团体、“2”表示民办非企业单位、“3”表示基金会、“9”表示其他
            sb.append("1");
            // 行政区划，共计6位
            String code = area.getCountyCode().substring(0, 6);
            sb.append(code);
            // 主体识别码
            sb.append("M");
            sb.append(RandomUtil.randomString(RandomUtil.BASE_CHAR_NUMBER, 8));
            // 校验码
            sb.append(RandomUtil.randomInt(1, 4));

            saveList.add(sb.toString().toUpperCase());
        }

        return saveList;
    }

    /**
     * 随机获取真实的统一信用代码
     *   注：由于早期统一信用代码并没有明确的规则，导致有一些统一信用代码是并不符合后来的规范的，另外，由于其生成规则有较多的验证，比如与注册地，注册类型
     *   注册机构，受理机构等等有关系，一般并没有收录如此详细的统一信用代码规则，故而将不考虑如此复杂的情况，直接从国家企业信用公示网获取一批数据，其中很多的企业
     *   已经注销，但也有在续存状态的企业，数量大概有1W多条，足够平常使用，故而这部分数据请勿用于真实系统之中。
     *
     *   另外，由于统一信用代码与注册地、企业类型等等有关联关系，故而，在使用该数据的时候，应该考虑到这些情况
     * @param num 生成数量，不会超过获取的最大值
     * @return
     */
    public static List<String> getRealUnifiedCreditCode(Integer num){
        String txt = ResourceUtil.readUtf8Str("unifiedCreditCode.txt");
        String[] array = txt.split("\r\n");
        List<String> list = Arrays.asList(array);

        if (num == null || num < 1){
            num = 1;
        }
        if (num > list.size()){
            num = list.size();
        }

        return RandomUtil.randomEleList(list, num);
    }


}
